package utils;

import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

import org.apache.log4j.Level;

import app_kvServer.ServerMetadata;

/**
 * CommonUtil is an utility class which stores methods for dealing with versatile tiny tasks not bounded to an application's business logic
 * @author Cipri Lucaci
 * @author Rustem Bekmukhametov
 * @author Alba Xhani
 */
public class CommonUtil {
	
	public static Level getLoggingLevel(String levelName){
		if(levelName.equalsIgnoreCase("all"))
			return Level.ALL;
		else if(levelName.equalsIgnoreCase("error"))
			return Level.ERROR;
		else if(levelName.equalsIgnoreCase("debug"))
			return Level.DEBUG;
		else if(levelName.equalsIgnoreCase("fatal"))
			return Level.FATAL;
		else if(levelName.equalsIgnoreCase("info"))
			return Level.INFO;
		else if(levelName.equalsIgnoreCase("warn"))
			return Level.WARN;
		else if(levelName.equalsIgnoreCase("off"))
			return Level.OFF;
		return null;
	}
	
	public static String convertStreamToString(java.io.InputStream is) {
	    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
	    return s.hasNext() ? s.next() : "";
	}
	
	public static byte[] stringToBytesASCII(String str) {
		byte[] b = new byte[str.length()];
		for (int i = 0; i < b.length; i++) {
			b[i] = (byte) str.charAt(i);
		}
		return b;
	}
	
	public static String hashString(byte[] data){
		if (data == null)
			return "";
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("MD5");
			md.update(data);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return "";
		}
 
        byte byteData[] = md.digest();
        
        StringBuffer hexString = new StringBuffer();
    	for (int i=0;i<byteData.length;i++) {
    		String hex=Integer.toHexString(0xff & byteData[i]);
   	     	if(hex.length()==1) hexString.append('0');
   	     	hexString.append(hex);
    	}
    	//System.out.println("Digest(in hex format):: " + hexString.toString());
    	return hexString.toString();
	}
	
	public static String hashString(String data){
		if (data == null)
			return "";
		if (data.length() == 0)
			return "";
		return hashString(data.getBytes());
	}
	
	public static int byteStringCompare(String a, String b){
		if(a.length()!=b.length())
			throw new IllegalArgumentException("the compared strings do not have the same length");
		for(int i=0; i<a.length(); i++){
			String ca = a.substring(i, i+1); 
			String cb = b.substring(i, i+1);
			int ia = Integer.valueOf(ca, 16);
			int ib = Integer.valueOf(cb, 16);
			if( ia < ib )
				return -1;
			if( ia > ib )
				return 1;
		}
		return 0 ;
		
		
	}
	
	public static String byteStringAddition(String data){
		BigInteger nr = new BigInteger(data, 16);
		BigInteger result = nr.add(new BigInteger("1"));
		
		byte byteData[] =result.toByteArray();
        
        StringBuffer hexString = new StringBuffer();
    	for (int i=0;i<byteData.length;i++) {
    		String hex=Integer.toHexString(0xff & byteData[i]);
   	     	if(hex.length()==1) hexString.append('0');
   	     	hexString.append(hex);
    	}
    	//System.out.println("Digest(in hex format):: " + hexString.toString());
    	String stringResult = hexString.toString();
    	int length = stringResult.length();
    	int index = 0;
    	if(length > 32){
	    	for(int i=0; i< length-32; i++){
	    		String ca = stringResult.substring(i,i+1);
	    		if(ca.equals("0"))
	    			index ++;
	    		else {
	    			stringResult = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
	    			break;
	    		}
	    	}
	    	stringResult = stringResult.substring(index);
    	}else if(length < 32){
    		for(int i=0; i<32-length; i++)
    			stringResult = "0"+stringResult;
    	}
    	
    	return stringResult;
	}
	
	public static void main(String[] args){
		System.out.println(byteStringCompare("BB", "bb"));
		System.out.println(byteStringAddition("BA"));
	}
	
	public static ServerMetadata extractMyMetadata(ArrayList<ServerMetadata> metadata, int port) {
		try {
			String myIp = InetAddress.getLocalHost().getHostAddress();
			for (ServerMetadata metaEntry: metadata) {
				if (metaEntry.getPort()==port) {
					if (metaEntry.getIpAddress().equals("localhost") || metaEntry.getIpAddress().equals(myIp)) {
						return metaEntry;
					}
				}
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
}
